home *** CD-ROM | disk | FTP | other *** search
- /*
- * strings.c - String input/output processing for nroff word processor
- *
- * adapted for atariST/TOS by Bill Rosenkranz 11/89
- * net: rosenkra@hall.cray.com
- * CIS: 71460,17
- * GENIE: W.ROSENKRANZ
- *
- * original author:
- *
- * Stephen L. Browning
- * 5723 North Parker Avenue
- * Indianapolis, Indiana 46220
- *
- * history:
- *
- * - Originally written in BDS C;
- * - Adapted for standard C by W. N. Paul
- * - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
- */
-
- #undef NRO_MAIN /* extern globals */
-
- #include <stdio.h>
- #include "nroff.h"
-
-
-
- /*------------------------------*/
- /* defstr */
- /*------------------------------*/
- defstr (p)
- register char *p;
- {
-
- /*
- * Define a string. top level, read from command line.
- *
- * we should read string without interpretation EXCEPT:
- *
- * 1) number registers are interpolated
- * 2) strings indicated by \* are interpolated
- * 3) arguments indicated by \$ are interpolated
- * 4) concealed newlines indicated by \(newline) are eliminated
- * 5) comments indicated by \" are eliminated
- * 6) \t and \a are interpreted as ASCII h tab and SOH.
- * 7) \\ is interpreted as backslash and \. is interpreted as a period.
- *
- * currently, we do only 3. a good place to do it would be here before
- * putstr, after colstr...
- */
-
- register char *q;
- register int i;
- char name[MNLEN];
- char defn[MXMLEN];
-
-
-
- name[0] = '\0';
- defn[0] = '\0';
-
-
- /*
- * skip the .ds and get to the name...
- */
- q = skipwd (p);
- q = skipbl (q);
-
- /*
- * ok, name now holds the name. make sure it is valid (i.e. first
- * char is alpha...). getwrd returns the length of the word.
- */
- i = getwrd (q, name);
- if (!name[0])
- {
- fprintf (err_stream,
- "***%s: missing or illegal string definition name\n",
- myname);
- err_exit (-1);
- }
-
- /*
- * truncate to 2 char max name.
- */
- if (i > 2)
- name[2] = EOS;
-
-
- /*
- * skip the name to get to the string. it CAN start with a " to
- * have leading blanks...
- */
- q = skipwd (q);
- q = skipbl (q);
-
-
-
- /*
- * read rest of line from input stream and collect string into
- * temp buffer defn
- */
- if ((i = colstr (q, defn)) == ERR)
- {
- fprintf (err_stream,
- "***%s: string definition too long\n", myname);
- err_exit (-1);
- }
-
-
- /*
- * store the string
- */
- if (putstr (name, defn) == ERR)
- {
- fprintf (err_stream,
- "***%s: string definition table full\n", myname);
- err_exit (-1);
- }
- }
-
-
-
-
-
- /*------------------------------*/
- /* colstr */
- /*------------------------------*/
- colstr (p, d)
- register char *p;
- char *d;
- {
-
- /*
- * Collect string definition from input stream
- */
-
- register int i = 0;
- char *pstart = p;
-
-
-
- /*
- * if there is a " here, we have leading blanks (skipbl in caller
- * found it). just get past it...
- */
- if (*p == '\"')
- p++;
-
-
- while (*p != EOS)
- {
- /*
- * are we over the length limit for a single string?
- */
- if (i >= MXMLEN - 1)
- {
- d[i - 1] = EOS;
- return (ERR);
- }
-
- /*
- * "i break for comments..."
- */
- if (*p == '\\' && *(p+1) == '\"')
- {
- /*
- * first back over any whitespace between comment
- * start and last character in line. remember to
- * decrement counter i, too...
- */
- p--;
- while (isspace (*p) && p > pstart && i > 0)
- {
- p--;
- i--;
- }
-
- /*
- * now skip over the comment until we reach the
- * trailing newline
- */
- while (*p != EOS)
- {
- if (*p == '\n' || *p == '\r')
- break;
- p++;
- }
- }
-
- /*
- * stop at the newline...
- */
- if (*p == '\n' || *p == '\r')
- break;
-
- /*
- * copy it
- */
- d[i++] = *p++;
- }
- d[i] = EOS;
- return (i);
- }
-
-
-
-
-
- /*------------------------------*/
- /* putstr */
- /*------------------------------*/
- putstr (name, p)
- register char *name;
- register char *p;
- {
-
- /*
- * Put string definition into (macro) table
- *
- * NOTE: any expansions of things like number registers SHOULD
- * have been done already. strings and macros share mb buffer
- */
-
-
- /*
- * any room left? (did we exceed max number of possible macros)
- */
- if (mac.lastp >= MXMDEF)
- return (ERR);
-
- /*
- * will new one fit in big buffer?
- */
- if (mac.emb + strlen (name) + strlen (p) + 1 > &mac.mb[MACBUF])
- {
- return (ERR);
- }
-
-
- /*
- * add it...
- *
- * bump counter, set ptr to name, copy name, copy def.
- * finally increment end of macro buffer ptr (emb).
- *
- * string looks like this in mb:
- *
- * mac.mb[MACBUF] size of total buf
- * lastp < MXMDEF number of macros/strings possible
- * *mnames[MXMDEF] -> names, each max length
- * ...______________________________...____________________...
- * / / /|X|X|0|string definition |0| / / / / / / /
- * .../_/_/_|_|_|_|_________________...___|_|/_/_/_/_/_/_/_...
- * ^
- * |
- * \----- mac.mnames[mac.lastp] points here
- *
- * both the 2 char name (XX) and the descripton are null term and
- * follow one after the other.
- */
- ++mac.lastp;
- mac.mnames[mac.lastp] = mac.emb;
- strcpy (mac.emb, name);
- strcpy (mac.emb + strlen (name) + 1, p);
- mac.emb += strlen (name) + strlen (p) + 2;
- return (OK);
- }
-
-
-
-
-
-
- /*------------------------------*/
- /* getstr */
- /*------------------------------*/
- char *getstr (name)
- register char *name;
- {
-
- /*
- * Get (lookup) string definition from namespace
- */
-
- register int i;
-
- /*
- * loop for all macros, starting with last one
- */
- for (i = mac.lastp; i >= 0; --i)
- {
- /*
- * is this REALLY a macro?
- */
- if (mac.mnames[i])
- {
- /*
- * if it compares, return a ptr to it
- */
- if (!strcmp (name, mac.mnames[i]))
- {
- /*!!!debug puts (mac.mnames[i]);*/
-
- if (mac.mnames[i][1] == EOS)
- return (mac.mnames[i] + 2);
- else
- return (mac.mnames[i] + 3);
- }
- }
- }
-
- /*
- * none found, return null
- */
- return (NULL_CPTR);
- }
-
-
-
-
-
-
-